package myJs.user.predict

import myJs.Implicits._
import myJs.CpLayer
import myJs.Utils._
import myJs.api.Api
import myJs.cps.{FormGroupInlineCp, NumInputCp, PureInputCp, Style}
import myJs.myPkg.{SwalOptions, layer, swal}
import myJs.myPkg.jquery.$
import myJs.myPkg.reactHookForm._
import org.scalajs.dom.{FormData, document, html}
import slinky.core.FunctionalComponent
import slinky.core.annotations.react
import slinky.core.facade.Hooks.{useEffect, useState}
import slinky.core.facade.{Fragment, React}
import slinky.web.html._

import scala.collection.immutable.SeqMap
import scala.concurrent.{Future, Promise}
import scala.scalajs.js
import scala.scalajs.js.Dynamic.{global => g}
import scala.scalajs.js.timers.SetTimeoutHandle
import scala.scalajs.js.{JSON, |}
import org.scalajs.macrotaskexecutor.MacrotaskExecutor.Implicits._
import com.softwaremill.quicklens._
import myJs.tool.Tool
import shared.pojo.Pojo.UserNameData
import shared.pojo.Pojo.predict._

/** Created by yz on 21/1/2022
  */
@react object Cp {

  val curPage = PredictP

  case class Props(
  )

  val component = FunctionalComponent[Props] { props =>
    val (data, setData) = useState(PredictData(userId = Tool.getUserId))
    val (missionId, setMissionId) = useState(812373)

    val useForm = ReactHookForm.useForm(UseFormOptions(mode = "onChange"))

    object FTool {

      def sampleIdChange = (v: String) => {
        val newData = data.modify(_.sampleId).setTo(v)
        setData(newData)
      }

      def nameChange = (v: String) => {
        val newData = data.modify(_.name).setTo(v)
        setData(newData)
      }

      def ageChange = (v: String) => {
        val newData = data.modify(_.age).setTo(v)
        setData(newData)
      }

      def astChange = (v: String) => {
        val newData = data.modify(_.ast).setTo(v)
        setData(newData)
      }

      def altChange = (v: String) => {
        val newData = data.modify(_.alt).setTo(v)
        setData(newData)
      }

      def pltChange = (v: String) => {
        val newData = data.modify(_.plt).setTo(v)
        setData(newData)
      }

      def tyrChange = (v: String) => {
        val newData = data.modify(_.tyr).setTo(v)
        setData(newData)
      }

      def tcaChange = (v: String) => {
        val newData = data.modify(_.tca).setTo(v)
        setData(newData)
      }

      def pheChange = (v: String) => {
        val newData = data.modify(_.phe).setTo(v)
        setData(newData)
      }

      def trpChange = (v: String) => {
        val newData = data.modify(_.trp).setTo(v)
        setData(newData)
      }

      def valineChange = (v: String) => {
        val newData = data.modify(_.valine).setTo(v)
        setData(newData)
      }

      def caChange = (v: String) => {
        val newData = data.modify(_.ca).setTo(v)
        setData(newData)
      }

      def metChange = (v: String) => {
        val newData = data.modify(_.met).setTo(v)
        setData(newData)
      }

      def gcaChange = (v: String) => {
        val newData = data.modify(_.gca).setTo(v)
        setData(newData)
      }

      def gcdcaChange = (v: String) => {
        val newData = data.modify(_.gcdca).setTo(v)
        setData(newData)
      }

      def tcdcaChange = (v: String) => {
        val newData = data.modify(_.tcdca).setTo(v)
        setData(newData)
      }

      def myRunBefore = () => {
        val request = UserNameData(name = Tool.getAccount)
        Api.user.getLimit(request).map { response =>
          if (!response) {
            val options =
              SwalOptions(title = "Error", text = "您无此权限使用该系统，请与管理员联系！", `type` = "error")
            swal(options)
            $("#myRun").attr("disabled", true)
          } else {
            FTool.myRun
          }
        }
        ()
      }

      def myRun = {
        val index = layer.alert(element, layerOptions)
        Api.predict.predict(data).map { response =>
          layer.close(index)
          if (!response.valid) {
            swal(SwalOptions(title = "错误", text = response.message, `type` = "error"))
            $("#result").hide()
          } else {
            setMissionId(response.missionId)
            g.reduceTime()
          }

        }
      }

    }

    CpLayer(title = curPage.titleStr)(
      div(
        className := "page-content",
        div(
          className := "page-bar",
          ul(
            className := "page-breadcrumb",
            li(
              i(className := "fa fa-picture-o"),
              " ",
              a(href := "#", "预测")
            )
          )
        ),
        div(
          className := "row-fluid",
          div(
            className := "row",
            div(
              className := "col-md-12 col-sm-12",
              div(
                className := "portlet green-jungle box",
                div(className := "portlet-title", div(className := "caption", "设置参数")),
                div(
                  className := "portlet-body",
                  form(
                    className := "registration-form form-horizontal",
                    onSubmit := {
                      useForm.handleSubmit((data: js.Dictionary[js.Any]) => {
                        println(JSON.stringify(data))
                        FTool.myRunBefore()
                      })
                    },
                    FormGroupInlineCp(useForm = useForm, names = List("sampleId"))(
                      label(className := "control-label col-sm-2", "样本号:"),
                      div(
                        className := "col-sm-3",
                        PureInputCp(
                          useForm = useForm,
                          name = "sampleId",
                          value = data.sampleId,
                          onChange = FTool.sampleIdChange,
                          registerOptions = RegisterOptions(
                            required = ValidationValueMessage(value = true, message = "样本号不能为空！")
                          )
                        )
                      ),
                      label(className := "control-label col-sm-2", "姓名:"),
                      div(
                        className := "col-sm-3",
                        PureInputCp(
                          useForm = useForm,
                          name = "name",
                          value = data.name,
                          onChange = FTool.nameChange
                        )
                      )
                    ),
                    FormGroupInlineCp(useForm = useForm, names = List("age", "ast"))(
                      label(className := "control-label col-sm-2", "年龄(18岁及以上):"),
                      div(
                        className := "col-sm-3",
                        NumInputCp(
                          useForm = useForm,
                          name = "age",
                          value = data.age,
                          onChange = FTool.ageChange,
                          registerOptions = RegisterOptions(
                            required = ValidationValueMessage(value = true, message = "年龄不能为空！"),
                            min = ValidationValueMessage(value = 18, message = "年龄必须处于18到100之间！"),
                            max = ValidationValueMessage(value = 100, message = "年龄必须处于18到100之间！")
                          )
                        )
                      ),
                      label(className := "control-label col-sm-2", "天门冬氨酸氨基转移酶 (U/L，0～1000):"),
                      div(
                        className := "col-sm-3",
                        NumInputCp(
                          useForm = useForm,
                          name = "ast",
                          value = data.ast,
                          onChange = FTool.astChange,
                          registerOptions = {
                            val (info, min, max) = ("天门冬氨酸氨基转移酶", 0, 1000)
                            val betweenInfo = s"${info}必须处于${min}到${max}之间！"
                            RegisterOptions(
                              required =
                                ValidationValueMessage(value = true, message = s"${info}不能为空！"),
                              min =
                                ValidationValueMessage(value = min, message = s"${betweenInfo}"),
                              max = ValidationValueMessage(value = max, message = s"${betweenInfo}")
                            )
                          }
                        )
                      )
                    ),
                    FormGroupInlineCp(useForm = useForm, names = List("alt", "plt"))(
                      label(className := "control-label col-sm-2", "丙氨酸氨基转移酶 (U/L，0～2000):"),
                      div(
                        className := "col-sm-3",
                        NumInputCp(
                          useForm = useForm,
                          name = "alt",
                          value = data.alt,
                          onChange = FTool.altChange,
                          registerOptions = {
                            val (info, min, max) = ("丙氨酸氨基转移酶", 0, 2000)
                            val betweenInfo = s"${info}必须处于${min}到${max}之间！"
                            RegisterOptions(
                              required =
                                ValidationValueMessage(value = true, message = s"${info}不能为空！"),
                              min =
                                ValidationValueMessage(value = min, message = s"${betweenInfo}"),
                              max = ValidationValueMessage(value = max, message = s"${betweenInfo}")
                            )
                          }
                        )
                      ),
                      label(className := "control-label col-sm-2", "血小板计数 (10^9/L，0～1000):"),
                      div(
                        className := "col-sm-3",
                        NumInputCp(
                          useForm = useForm,
                          name = "plt",
                          value = data.plt,
                          onChange = FTool.pltChange,
                          registerOptions = {
                            val (info, min, max) = ("血小板计数", 0, 1000)
                            val betweenInfo = s"${info}必须处于${min}到${max}之间！"
                            RegisterOptions(
                              required =
                                ValidationValueMessage(value = true, message = s"${info}不能为空！"),
                              min =
                                ValidationValueMessage(value = min, message = s"${betweenInfo}"),
                              max = ValidationValueMessage(value = max, message = s"${betweenInfo}")
                            )
                          }
                        )
                      )
                    ),
                    FormGroupInlineCp(useForm = useForm, names = List("tyr", "tca"))(
                      label(className := "control-label col-sm-2", "L-酪氨酸 (μmol/L，5～1000):"),
                      div(
                        className := "col-sm-3",
                        NumInputCp(
                          useForm = useForm,
                          name = "tyr",
                          value = data.tyr,
                          onChange = FTool.tyrChange,
                          registerOptions = {
                            val (info, min, max) = ("L-酪氨酸", 5, 1000)
                            val betweenInfo = s"${info}必须处于${min}到${max}之间！"
                            RegisterOptions(
                              required =
                                ValidationValueMessage(value = true, message = s"${info}不能为空！"),
                              min =
                                ValidationValueMessage(value = min, message = s"${betweenInfo}"),
                              max = ValidationValueMessage(value = max, message = s"${betweenInfo}")
                            )
                          }
                        )
                      ),
                      label(className := "control-label col-sm-2", "牛磺胆酸 (ng/mL):"),
                      div(
                        className := "col-sm-3",
                        NumInputCp(
                          useForm = useForm,
                          name = "tca",
                          value = data.tca,
                          onChange = FTool.tcaChange,
                          registerOptions = {
                            val info = "牛磺胆酸"
                            RegisterOptions(
                              required =
                                ValidationValueMessage(value = true, message = s"${info}不能为空！"),
                              pattern = ValidationValueMessage(
                                value = Tool.positiveDoubleRegexp,
                                message = s"${info}必须为正实数！"
                              )
                            )
                          }
                        )
                      )
                    ),
                    FormGroupInlineCp(useForm = useForm, names = List("phe", "trp"))(
                      label(className := "control-label col-sm-2", "苯丙氨酸（μmol/L，5～1000）:"),
                      div(
                        className := "col-sm-3",
                        NumInputCp(
                          useForm = useForm,
                          name = "phe",
                          value = data.phe,
                          onChange = FTool.pheChange,
                          registerOptions = {
                            val (info, min, max) = ("苯丙氨酸", 5, 1000)
                            val betweenInfo = s"${info}必须处于${min}到${max}之间！"
                            RegisterOptions(
                              required =
                                ValidationValueMessage(value = true, message = s"${info}不能为空！"),
                              pattern = ValidationValueMessage(
                                value = Tool.positiveDoubleRegexp,
                                message = s"${info}必须为正实数！"
                              ),
                              min =
                                ValidationValueMessage(value = min, message = s"${betweenInfo}"),
                              max = ValidationValueMessage(value = max, message = s"${betweenInfo}")
                            )
                          }
                        )
                      ),
                      label(className := "control-label col-sm-2", "色氨酸（μmol/L，5～1000）:"),
                      div(
                        className := "col-sm-3",
                        NumInputCp(
                          useForm = useForm,
                          name = "trp",
                          value = data.trp,
                          onChange = FTool.trpChange,
                          registerOptions = {
                            val (info, min, max) = ("色氨酸", 5, 1000)
                            val betweenInfo = s"${info}必须处于${min}到${max}之间！"
                            RegisterOptions(
                              required =
                                ValidationValueMessage(value = true, message = s"${info}不能为空！"),
                              pattern = ValidationValueMessage(
                                value = Tool.positiveDoubleRegexp,
                                message = s"${info}必须为正实数！"
                              ),
                              min =
                                ValidationValueMessage(value = min, message = s"${betweenInfo}"),
                              max = ValidationValueMessage(value = max, message = s"${betweenInfo}")
                            )
                          }
                        )
                      )
                    ),
                    FormGroupInlineCp(useForm = useForm, names = List("valine", "ca"))(
                      label(className := "control-label col-sm-2", "缬氨酸（μmol/L，5～1000）:"),
                      div(
                        className := "col-sm-3",
                        NumInputCp(
                          useForm = useForm,
                          name = "valine",
                          value = data.valine,
                          onChange = FTool.valineChange,
                          registerOptions = {
                            val (info, min, max) = ("缬氨酸", 5, 1000)
                            val betweenInfo = s"${info}必须处于${min}到${max}之间！"
                            RegisterOptions(
                              required =
                                ValidationValueMessage(value = true, message = s"${info}不能为空！"),
                              pattern = ValidationValueMessage(
                                value = Tool.positiveDoubleRegexp,
                                message = s"${info}必须为正实数！"
                              ),
                              min =
                                ValidationValueMessage(value = min, message = s"${betweenInfo}"),
                              max = ValidationValueMessage(value = max, message = s"${betweenInfo}")
                            )
                          }
                        )
                      ),
                      label(className := "control-label col-sm-2", "胆酸（μmol/L）:"),
                      div(
                        className := "col-sm-3",
                        NumInputCp(
                          useForm = useForm,
                          name = "ca",
                          value = data.ca,
                          onChange = FTool.caChange,
                          registerOptions = {
                            val info = "胆酸"
                            RegisterOptions(
                              required =
                                ValidationValueMessage(value = true, message = s"${info}不能为空！"),
                              pattern = ValidationValueMessage(
                                value = Tool.positiveDoubleRegexp,
                                message = s"${info}必须为正实数！"
                              )
                            )
                          }
                        )
                      )
                    ),
                    FormGroupInlineCp(useForm = useForm, names = List("met", "gca"))(
                      label(className := "control-label col-sm-2", "甲硫氨酸（μmol/L，5～1000）:"),
                      div(
                        className := "col-sm-3",
                        NumInputCp(
                          useForm = useForm,
                          name = "met",
                          value = data.met,
                          onChange = FTool.metChange,
                          registerOptions = {
                            val (info, min, max) = ("甲硫氨酸", 5, 1000)
                            val betweenInfo = s"${info}必须处于${min}到${max}之间！"
                            RegisterOptions(
                              required =
                                ValidationValueMessage(value = true, message = s"${info}不能为空！"),
                              pattern = ValidationValueMessage(
                                value = Tool.positiveDoubleRegexp,
                                message = s"${info}必须为正实数！"
                              ),
                              min =
                                ValidationValueMessage(value = min, message = s"${betweenInfo}"),
                              max = ValidationValueMessage(value = max, message = s"${betweenInfo}")
                            )
                          }
                        )
                      ),
                      label(className := "control-label col-sm-2", "甘氨氧胆酸（μmol/L）:"),
                      div(
                        className := "col-sm-3",
                        NumInputCp(
                          useForm = useForm,
                          name = "gca",
                          value = data.gca,
                          onChange = FTool.gcaChange,
                          registerOptions = {
                            val info = "甘氨氧胆酸"
                            RegisterOptions(
                              required =
                                ValidationValueMessage(value = true, message = s"${info}不能为空！"),
                              pattern = ValidationValueMessage(
                                value = Tool.positiveDoubleRegexp,
                                message = s"${info}必须为正实数！"
                              )
                            )
                          }
                        )
                      )
                    ),
                    FormGroupInlineCp(useForm = useForm, names = List("gcdca", "tcdca"))(
                      label(className := "control-label col-sm-2", "甘氨鹅脱氧胆酸（μmol/L）:"),
                      div(
                        className := "col-sm-3",
                        NumInputCp(
                          useForm = useForm,
                          name = "gcdca",
                          value = data.gcdca,
                          onChange = FTool.gcdcaChange,
                          registerOptions = {
                            val info = "甘氨鹅脱氧胆酸"
                            RegisterOptions(
                              required =
                                ValidationValueMessage(value = true, message = s"${info}不能为空！"),
                              pattern = ValidationValueMessage(
                                value = Tool.positiveDoubleRegexp,
                                message = s"${info}必须为正实数！"
                              )
                            )
                          }
                        )
                      ),
                      label(className := "control-label col-sm-2", "牛磺鹅脱氧胆酸（μmol/L）:"),
                      div(
                        className := "col-sm-3",
                        NumInputCp(
                          useForm = useForm,
                          name = "tcdca",
                          value = data.tcdca,
                          onChange = FTool.tcdcaChange,
                          registerOptions = {
                            val info = "牛磺鹅脱氧胆酸"
                            RegisterOptions(
                              required =
                                ValidationValueMessage(value = true, message = s"${info}不能为空！"),
                              pattern = ValidationValueMessage(
                                value = Tool.positiveDoubleRegexp,
                                message = s"${info}必须为正实数！"
                              )
                            )
                          }
                        )
                      )
                    ),
                    div(
                      className := "form-group",
                      div(
                        className := "actions col-sm-offset-2 col-sm-2",
                        button(
                          `type` := "submit",
                          className := "btn btn-primary",
                          style := Style(width = "90%"),
                          s" 运行"
                        )
                      )
                    )
                  )
                )
              )
            )
          ),
          PredictResultCp(missionId = missionId),
        )
      )
    )

  }

}
